﻿using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using TotalApplication.Core;

namespace TotalApplication.AngelSix
{
    /// <summary>
    /// PageHost.xaml 的交互逻辑
    /// </summary>
    public partial class PageHost : UserControl
    {

        #region Public member

        public ApplicationPage CurrentPage
        {
            get { return (ApplicationPage)GetValue(CurrentPageProperty); }
            set { SetValue(CurrentPageProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CurrentPage. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CurrentPageProperty =
            DependencyProperty.Register(nameof(CurrentPage), typeof(ApplicationPage), typeof(PageHost), new PropertyMetadata(default(ApplicationPage), null, CurrentPagePropertyChanged));

        public BaseViewModel CurrentPageViewModel
        {
            get { return (BaseViewModel)GetValue(CurrentPageViewModelProperty); }
            set { SetValue(CurrentPageViewModelProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CurrentPage. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CurrentPageViewModelProperty =
            DependencyProperty.Register(nameof(CurrentPageViewModel), typeof(BaseViewModel), typeof(PageHost), new PropertyMetadata());

        #endregion

        #region Constructor
        /// <summary>
        /// Default constructor
        /// </summary>
        public PageHost()
        {
            InitializeComponent();

            if (DesignerProperties.GetIsInDesignMode(this))
            {
                // In design mode, set the current page to a design page
                NewPage.Content = IoC.Application.CurrentPage.ToBasePage();
            }
        }
        #endregion

        #region Property changed events

        private static object CurrentPagePropertyChanged(DependencyObject d, object value)
        {
            var currentPage = (ApplicationPage)value;
            // var currentPage = (ApplicationPage)d.GetValue(CurrentPageProperty);
            var currentPageViewModel = d.GetValue(CurrentPageViewModelProperty);

            var newPageFrame = ((PageHost)d).NewPage;
            var oldPageFrame = ((PageHost)d).OldPage;

            // If the page is the same as current, Just update the view model
            if (newPageFrame.Content is BasePage page && currentPage == (ApplicationPage)d.GetValue(CurrentPageProperty))
            {
                page.ViewModelObject = currentPageViewModel ?? new BaseViewModel();

                return value;
            }

            // Store the current page content as the old page
            var oldPageContent = newPageFrame.Content;

            // Remove the current page from new page frame 
            newPageFrame.Content = null;

            // Move the previous page into the old frame
            oldPageFrame.Content = oldPageContent;

            // Animate out the previous page when the loaded event fires
            // right after the call due to moving frames
            if (oldPageContent is BasePage oldPage)
            {
                // Tell old page to animate out
                oldPage.ShouldAnimateOut = true;

                // Once it done, remove the old page
                Task.Delay((int)(oldPage.SlideSeconds * 1000)).ContinueWith((t) =>
                {
                    // Remove old page
                    //oldPageFrame.Dispatcher.Invoke(() =>
                    //{
                    //    oldPageFrame.Content = null;
                    //});

                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        // Clear old page
                        oldPageFrame.Content = null;
                    });
                });
            }

            // Set the new page content
            newPageFrame.Content = currentPage.ToBasePage((BaseViewModel)currentPageViewModel);

            return value;
        }

        #endregion
    }
}
